package com.zengdada.authority.config.quartz;

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: 12614
 * @Contact: 1261438511@qq.com
 * @Date: 2018/11/20 10:25
 * @Description:
 */
@Service
@Slf4j
public class JobAndTriggerManager {

    @Autowired
    private Scheduler scheduler;

//    @PostConstruct
//    public void initMethod() {
//        try {
//            scheduler.getListenerManager().addSchedulerListener(new SchedulerListener() {
//                @Override
//                public void jobScheduled(Trigger trigger) {
//
//                }
//
//                @Override
//                public void jobUnscheduled(TriggerKey triggerKey) {
//
//                }
//
//                @Override
//                public void triggerFinalized(Trigger trigger) {
//
//                }
//
//                @Override
//                public void triggerPaused(TriggerKey triggerKey) {
//
//                }
//
//                @Override
//                public void triggersPaused(String triggerGroup) {
//
//                }
//
//                @Override
//                public void triggerResumed(TriggerKey triggerKey) {
//
//                }
//
//                @Override
//                public void triggersResumed(String triggerGroup) {
//
//                }
//
//                @Override
//                public void jobAdded(JobDetail jobDetail) {
//
//                }
//
//                @Override
//                public void jobDeleted(JobKey jobKey) {
//
//                }
//
//                @Override
//                public void jobPaused(JobKey jobKey) {
//
//                }
//
//                @Override
//                public void jobsPaused(String jobGroup) {
//
//                }
//
//                @Override
//                public void jobResumed(JobKey jobKey) {
//
//                }
//
//                @Override
//                public void jobsResumed(String jobGroup) {
//
//                }
//
//                @Override
//                public void schedulerError(String msg, SchedulerException cause) {
//
//                }
//
//                @Override
//                public void schedulerInStandbyMode() {
//
//                }
//
//                @Override
//                public void schedulerStarted() {
//                    System.out.printf("");
//
//
//                }
//
//                @Override
//                public void schedulerStarting() {
//
//                }
//
//                @Override
//                public void schedulerShutdown() {
//                    System.out.printf("schedulerShutdown");
//
//                }
//
//                @Override
//                public void schedulerShuttingdown() {
//
//                }
//
//                @Override
//                public void schedulingDataCleared() {
//
//                }
//            });
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        }
//    }


    public Map<String, Object> getJobInfo(TriggerKey triggerKey) throws SchedulerException {
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        Map<String, Object> map = new HashMap<>();
        if (cronTrigger != null) {
            map.put("taskState", getJobState(triggerKey).name());
            map.put("taskCron", cronTrigger.getCronExpression());
            map.put("taskStartTime", cronTrigger.getStartTime());
            map.put("taskPreviousFireTime", cronTrigger.getPreviousFireTime());
            map.put("taskNextFireTime", cronTrigger.getNextFireTime());
        }
        return map;
    }

    public Trigger.TriggerState getJobState(TriggerKey triggerKey) throws SchedulerException {
        return scheduler.getTriggerState(triggerKey);
    }

    /**
     * 获取Job信息
     *
     * @param jobName
     * @param jobGroupName
     * @return
     * @throws SchedulerException
     */
    public Map<String, Object> getJobInfo(String jobName, String jobGroupName) throws SchedulerException {
        return getJobInfo(new TriggerKey(jobName, jobGroupName));
    }

    public void addJob(String jobClassName, TriggerKey key, String cronExpression, Map<String, Object> param) throws Exception {
        // 如果定时器还没启动则 启动调度器
        if (!scheduler.isStarted()) scheduler.start();
        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
                .withIdentity(key.getName(), key.getGroup()).build();
        if (param != null) jobDetail.getJobDataMap().putAll(param);
        // 表达式调度构建器(即任务执行的时间)
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
        // 按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(key)
                .withSchedule(scheduleBuilder).build();
        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.debug(e.getMessage());
            throw new Exception("创建定时任务失败");
        }

    }

    public void addJob(String jobClassName, String jobName, String jobGroupName, String cronExpression, Map<String, Object> param) throws Exception {
        // 如果定时器还没启动则 启动调度器
        if (!scheduler.isStarted()) scheduler.start();
        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
                .withIdentity(jobName, jobGroupName).build();
        if (param != null) jobDetail.getJobDataMap().putAll(param);
        // 表达式调度构建器(即任务执行的时间)
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
        // 按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                .withSchedule(scheduleBuilder).build();
        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.debug(e.getMessage());
            throw new Exception("创建定时任务失败");
        }

    }

    public void updateJob(TriggerKey key, String cronExpression) throws Exception {
        updateJob(key.getName(), key.getGroup(), cronExpression);
    }

    public void updateJob(String jobName, String jobGroupName, String cronExpression) throws Exception {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            throw new Exception("更新定时任务失败" + e.getMessage());
        }
    }

    public void deleteJob(TriggerKey triggerKey) throws Exception {
        scheduler.pauseTrigger(triggerKey);
        scheduler.unscheduleJob(triggerKey);
        scheduler.deleteJob(JobKey.jobKey(triggerKey.getName(), triggerKey.getGroup()));
        if (log.isDebugEnabled()) log.debug("移除定时任务:{},{}", triggerKey.getName(), triggerKey.getGroup());
    }


    public void deleteJob(String jobName, String jobGroupName) throws Exception {
        deleteJob(TriggerKey.triggerKey(jobName, jobGroupName));
    }

    public void pauseJob(TriggerKey triggerKey) throws SchedulerException {
        pauseJob(triggerKey.getName(), triggerKey.getGroup());
    }

    public void pauseJob(String jobName, String jobGroupName) throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
    }

    public void resumeJob(TriggerKey triggerKey) throws SchedulerException {
        resumeJob(triggerKey.getName(), triggerKey.getGroup());
    }

    public void resumeJob(String jobName, String jobGroupName) throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
    }

    public static BaseJob getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (BaseJob) class1.newInstance();
    }

}
